#include "Map.h"

Map::Map(std::vector<Unit*> &units) : units(units) {
    width = 0;
    height = 0;
    tileMap = NULL;

    terrainImages[TR_GRASS].LoadFromFile("gfx/Grass Block.png");
    terrainImages[TR_DIRT].LoadFromFile("gfx/Dirt Block.png");
    terrainImages[TR_STONE].LoadFromFile("gfx/Stone Block.png");
    terrainImages[TR_WATER].LoadFromFile("gfx/Water Block.png");
    //image->SetSmooth(false);
}

Map::~Map() { 
    UnLoad();
}

int Map::GetWidth() {
    return width;
}

int Map::GetHeight() {
    return height;
}

Tile *Map::GetTile(int x, int y) {
    if (x < 0 || x >= width) return NULL;
    if (y < 0 || y >= height) return NULL;

    return &tileMap[y*width + x];
}

Unit *Map::GetTileUnit(int x, int y) {
    return GetTile(x, y)->unit;
}

void Map::MoveUnit(int oldX, int oldY, int newX, int newY) {
    int newIndex = newY*width + newX;
    int oldIndex = oldY*width + oldX;
    tileMap[newIndex].unit = tileMap[oldIndex].unit;
    tileMap[oldIndex].unit = NULL;
}

void Map::PopulateTiles() {
    for (int i=0; i<width*height; i++) {
        tileMap[i].unit = NULL;
    }
    for (int i=0; i<units.size(); i++) {
        Tile *tile = GetTile(units[i]->GetTileX(), units[i]->GetTileY());
        tile->unit = units[i];
    } 
}

bool Map::Load(const char *fileName) {
    // open map file
    std::ifstream in(fileName);
    
    // read in map size
    in >> width;
    in >> height;
    
    // error if either is 0
    if (width == 0 || height == 0) return false;

    // initialize and fill tileMap
    tileMap = new Tile [width * height];
    int i = 0;
    int t = 0;
    while (in >> t) {
        tileMap[i].sprite.SetImage(terrainImages[t]);
        tileMap[i].sprite.SetPosition(i%width * TILE_SIZE, i/width * TILE_SIZE);
        tileMap[i].sprite.SetCenter(0,50);
        tileMap[i].terrain = t;
        i++;
    }

    // error if # of tiles doesn't match map size
    if (i != width*height) return false;

    // success
    return true;
}

void Map::UnLoad() {
    width = 0;
    height = 0;
    
    // delete tileMap if not NULL
    if (tileMap != NULL) {
        delete [] tileMap;
        tileMap = NULL;
    }
}

void Map::Update(float dt) {
}

void Map::Render(SpriteManager &spriteManager) {
    for (int i = 0; i < width * height; i++) {
        // draw each tile
        spriteManager.Draw(tileMap[i].sprite);
    }
}
